package com.yanfan.dlt698_45;

import io.netty.buffer.ByteBuf;

/**
 * @author oliver foo
 * @description
 * @date 2023/3/21 9:04
 */
public class DLT698Utils {


    /**
     * 协议默认启始符
     */
    public static final short DEFAULT_DLT698_START_ID = 0x68;

    /**
     * 协议默认结束符
     */
    public static final short DEFAULT_DLT698_END_ID = 0x16;

    /**
     * 唤醒符号
     */
    public static final short DEFAULT_DLT698_WAKE_CODE = 0xFE;


    /**
     * 校验所属 表格
     */
    public static final int[] FCS_16_TABLE = generateFCSTable();


    /**
     * 获取控制位
     *
     * @param destination
     * @param hasFollowFrame
     * @param functionCode
     * @return
     */
    public static byte getControlCode(byte destination, boolean hasFollowFrame, byte functionCode) {
        return (byte) ((destination << 6) + ((hasFollowFrame ? 1 : 0) << 5) + (functionCode & 0xFF));
    }

    public static byte[] geAddressBytes(byte[] address, byte addressType) {
        //取值范围：0…15，对应表示1…16个字节长度
        int addressBytes = address.length - 1;
        // 地址特征值
        byte addressDescCode = (byte) ((addressType << 6) + (addressBytes & 0x0F));
        byte[] bytes = new byte[address.length + 1];
        bytes[0] = addressDescCode;
        System.arraycopy(address, 0, bytes, 1, address.length);
        return bytes;
    }

    /**
     * 两个高位是  保留为0
     *
     * @param length
     * @return
     */
    public static short getHeaderLength(int length) {
        int data = (length & 0b001111111111111);
        return (short) ((data << 8 | data >> 8) & 0xFFFF);

    }

    public static short decodeFrameLength(int length) {
        short data = (short) ((length << 8 | length >> 8) & 0xFFFF);
        return (short) (data & 0b001111111111111);

    }


    /**
     * 生成  FCS-16 校验所需的表格
     *
     * @return
     */
    public static int[] generateFCSTable() {
        int POLY = 0x8408; // FCS-16 generator polynomial
        int[] table = new int[256];
        for (int i = 0; i < 256; i++) {
            int crc = i;
            for (int j = 0; j < 8; j++) {
                if ((crc & 1) != 0) {
                    crc = (crc >>> 1) ^ POLY;
                } else {
                    crc >>>= 1;
                }
            }
            table[i] = crc & 0xFFFF;
        }
        return table;
    }

    public static short computeFcs16(ByteBuf buffer) {
        int fcs = 0xFFFF;
        for (int i = 0; i < buffer.readableBytes(); i++) {
            byte b = buffer.getByte(i);
            fcs = (fcs >>> 8) ^ FCS_16_TABLE[(fcs ^ b) & 0xFF];
        }
        fcs = fcs ^ 0xFFFF;
        //将前八位和后八位互换位置
        return (short) ((fcs << 8 | fcs >> 8) & 0xFFFF);
    }

    /**
     * 两个两个翻转字符串
     *
     * @return
     */
    public static String reverseTwo(String str) {
        StringBuilder sb = new StringBuilder();
        int len = str.length();
        if (len % 2 != 0) {
            len = len - 1;
        }
        for (int i = len; i > 0; i -= 2) {
            sb.append(str, i - 2, i);
        }
        return sb.toString();
    }


    public static void main(String[] args) {
        System.out.println(decodeFrameLength(10240));
    }
}
